home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / bin / ical2vcal < prev    next >
Text File  |  2008-10-20  |  11KB  |  455 lines

  1. #! /usr/bin/perl
  2. # THE ABOVE LINE SHOULD POINT TO YOUR PERL EXECUTABLE!
  3. # ical2vcal
  4. # (c) 1998 Preston Brown
  5. # Part of the KOrganizer Project
  6. #
  7. # This utility will read ~/.calendar in the ical format as input, and output 
  8. # a file in the versit vCalendar format with a .vcs extension.
  9. #
  10. # This code is covered by the GNU Public License.  Please see the file
  11. # COPYING for more information.
  12. #
  13. # MINIMAL ERROR CHECKING!  HIGHLY PRIMITIVE!  YOU HAVE BEEN WARNED!
  14.  
  15. # open the calendar.
  16. $home = $ENV{"HOME"};
  17. $pcount = 0;
  18.  
  19. $exitstatus = 0;
  20.  
  21. $filename = "$home/.calendar";
  22.  
  23. if (defined($ARGV[0]) && defined($ARGV[1])) {
  24.     $filename = $ARGV[0];
  25.     $outfilename = $ARGV[1];
  26. } elsif (defined($ARGV[0])) {
  27.     $outfilename = $ARGV[0];
  28. } else {
  29.     exit -1;
  30. }
  31.  
  32. if (!open(ICALFILE, $filename)) {
  33.     exit -1;
  34. }
  35. if (!open(VCALFILE, ">$outfilename")) {
  36.     exit -1;
  37. }
  38.  
  39. $line = <ICALFILE>;
  40.  
  41. &write_header;
  42.  
  43. if ($line =~ /Calendar(\s+)\[v/) {
  44.     while ($line = &getLine) {
  45.     if (($line =~ /^Appt/) || ($line =~ /^Note/)) {
  46.         &process_appointment;
  47.         &write_appointment;
  48.     } else {
  49.         # silently skip line
  50.     }
  51.     }
  52. } else {
  53.     # not a ical file?!
  54.     exit -2;
  55. }
  56.  
  57. close(ICALFILE);
  58. close(VCALFILE);
  59.  
  60. sub getLine
  61. {
  62.     $_ = <ICALFILE>;
  63.     if (!defined($_)) {
  64.     &write_footer;
  65.     exit $exitstatus;
  66.     }
  67.     s/\\\[/\(/g;
  68.     s/\\\]/\)/g;
  69.     $pcount += tr/\[//;
  70.     $pcount -= tr/\]//;
  71.     return $_;
  72. }
  73.  
  74. sub process_appointment
  75. {
  76.     undef(%curappt);
  77.  
  78.     # this is a count of the total # of parentheses.
  79.     while ($pcount) {
  80.     $line = &getLine;
  81.     
  82.     # check to see if more is left to be processed.
  83.     if ($pcount > 0) {
  84.          # process the line.
  85.  
  86.          if ($line =~ /^Start/) {
  87.         # start time (minutes since midnight)
  88.          $_ = $line;
  89.          ($totalmin) = /\[(\d+)\]/;
  90.          $min = $totalmin % 60;
  91.          $hour = int ($totalmin / 60);
  92.          $curappt{"starthour"} = $hour;
  93.          $curappt{"startmin"} = $min;
  94.         
  95.          } elsif ($line =~ /^Length/) {
  96.         # time length (minutes)
  97.          $_ = $line;
  98.          ($lengthmin) = /\[(\d+)\]/;
  99.          $min = $lengthmin % 60;
  100.          $hour = int ($lengthmin / 60);
  101.          $curappt{"endhour"} = $hour;
  102.          $curappt{"endmin"} = $min;
  103.         } elsif ($line =~ /^Uid/) {
  104.         # unique identifier
  105.         $_ = $line;
  106.         ($uid) = /\[(.+)\]/;
  107.         $curappt{"uid"} = $uid ;
  108.         } elsif ($line =~ /^Owner/) {
  109.         # appointment's owner
  110.         $_ = $line;
  111.         ($attendee) = /\[(\w+)\]/;
  112.         $curappt{"attendee"} = $attendee;
  113.         } elsif ($line =~ /^Contents/) {
  114.         # description
  115.         $description = "";
  116.         $_ = $line;
  117.         # special case where it's all in one place:
  118.         if (/\[(.*)\]/) {
  119.             $summary = $1;
  120.         } else {
  121.             ($summary) = /\[(.*)/;
  122.             $_ = &getLine;
  123.             while (!(/\]$/)) {
  124.             chop;
  125.             $description = $description . " " . $_;
  126.             $_ = &getLine;
  127.             }
  128.             /(.*)\]$/;
  129.             $description = $description . $1;
  130.         }
  131.         $curappt{"summary"} = $summary;
  132.         if (length($description) > 0) {
  133.             $summary = $summary . "...";
  134.             $curappt{"description"} = $description;
  135.         }
  136.         } elsif ($line =~ /^Text/) {
  137.         $description = "";
  138.         $_ = $line;
  139.         if (/\[\d+\s+\[(.*)\]\]/) {
  140.             $summary = $1;
  141.         } else {
  142.             ($summary) = /\[\d+\s+\[(.*)$/;
  143.             $_ = &getLine;
  144.             while (!(/\]$/)) {
  145.             chop;
  146.             $description = $description . " " . $_;
  147.             $_ = &getLine;
  148.             }
  149.             /^(.*)\]\]/;
  150.             $description = $description . $1;
  151.         }
  152.         $curappt{"summary"} = $summary;
  153.         if (length($description) > 0) {
  154.             $summary = $summary . "...";
  155.             $curappt{"description"} = $description;
  156.         }
  157.         } elsif ($line =~ /^Alarms/) {
  158.         $_ = $line;
  159.         ($alarm) = /(\d+)\]/;
  160.         $curappt{"alarmtime"} = $alarm;
  161.         } elsif ($line =~ /^Todo/) {
  162.         $curappt{"todo"} = 1;
  163.         } elsif ($line =~ /^Dates/) {
  164.         # dates to occur on
  165.         &process_dates;
  166.         } elsif ($line =~ /^\]/) {
  167.         # do nothing
  168.         } elsif ($line =~ /^Hilite/) {
  169.         # do nothing
  170.         } elsif ($line =~ /^Remind/) {
  171.         # do nothing
  172.         } elsif ($line =~ /^Done/) {
  173.         $curappt{"done"}=1;
  174.         } else {
  175.         # do nothing
  176.         ;
  177.         }
  178.  
  179.     } # if $pcount > 0
  180.  
  181.     } # while pcount
  182.  
  183.     if (defined($curappt{"starthour"})) {
  184.     # fix up end time, just peg it at the end of the day
  185.     $endhour = $curappt{"starthour"} + $curappt{"endhour"};
  186.     $endmin = $curappt{"startmin"} + $curappt{"endmin"};
  187.     $endhour = $endhour + int ($endmin / 60);
  188.     $endmin = $endmin % 60;
  189.     $curappt{"endhour"} = $endhour;
  190.     $curappt{"endmin"} = $endmin;
  191.     if ($endhour >= 24) {
  192.         $curappt{"endhour"} = 23;
  193.         $curappt{"endmin"} = 55;
  194.     }
  195.     }
  196. }
  197.  
  198. sub output
  199. {
  200.     $outline = shift(@_);
  201.     print VCALFILE $outline;
  202.     print VCALFILE "\n";
  203. #    print($outline);
  204. #    print("\n");
  205. }
  206.  
  207. sub write_header
  208. {
  209.     output("BEGIN:VCALENDAR");
  210.     output("PRODID:-//K Desktop Environment//NONSGML KOrganizer//EN");
  211.     output("VERSION:1.0");
  212. }
  213.  
  214. sub write_footer
  215. {
  216.     output("END:VCALENDAR");
  217. }
  218.  
  219. sub write_appointment
  220. {
  221.     if (defined($curappt{"tossme"})) {
  222.     return;
  223.     }
  224.  
  225.     if (defined($curappt{"todo"})) {
  226.     output("BEGIN:VTODO");
  227.     } else {
  228.     output("BEGIN:VEVENT");
  229.     }
  230.     $tmpstr = &date_to_str($curappt{"startyear"},
  231.                $curappt{"startmonth"},
  232.                $curappt{"startday"});
  233.     if (defined($curappt{"starthour"})) {
  234.     $tmpstr = $tmpstr . &time_to_str($curappt{"starthour"},
  235.                    $curappt{"startmin"});
  236.     } else {
  237.     $tmpstr = $tmpstr . &time_to_str("0","0");
  238.     }
  239.     output("DCREATED:" . $tmpstr);
  240.     output("UID:" . $curappt{"uid"});
  241.     output("SEQUENCE:0");
  242.     output("LAST-MODIFIED:$tmpstr");
  243.     output("DTSTART:$tmpstr");
  244.     if (defined($curappt{"starthour"})) {
  245.     $tmpstr = &date_to_str($curappt{"startyear"},
  246.                   $curappt{"startmonth"},
  247.                   $curappt{"startday"}) . 
  248.                   &time_to_str($curappt{"endhour"},
  249.                            $curappt{"endmin"});
  250.     } 
  251.     output("DTEND:$tmpstr");
  252.     if (defined($curappt{"summary"})) {
  253.     $summary = $curappt{"summary"};
  254.     output("SUMMARY:$summary");
  255.     }
  256.     if (defined($curappt{"description"})) {
  257.     $description = $curappt{"description"};
  258.     output("DESCRIPTION:$description");
  259.     }
  260.     if (defined($curappt{"attendee"})) {
  261.     $attendee = "ATTENDEE;ROLE=OWNER:" . $curappt{"attendee"};
  262.     output($attendee);
  263.     }
  264.     
  265.     if (defined($curappt{"alarm"})) {
  266.     
  267.     }
  268.  
  269.     if (defined($curappt{"repeats"})) {
  270.     # wow what a mess
  271.     $rule = "RRULE:";
  272.     if ($curappt{"repeats"} eq "DAILY") {
  273.         $rule = $rule . "D" . $curappt{"period"};
  274.     } elsif ($curappt{"repeats"} eq "WEEKLY") {
  275.         $rule = $rule . "W1" . " ";
  276.         $rule = $rule . $curappt{"weekdays"};
  277.         
  278.     } elsif ($curappt{"repeats"} eq "MONTHLY") {
  279.         $rule = $rule . "MD" . $curappt{"period"};
  280.         $rule = $rule . " " . $curappt{"startday"};
  281.     }
  282.     if ($curappt{"endrepeat"} && ($curappt{"endrepeat"} =~ /T/)) {
  283.         $rule = $rule . " " . $curappt{"endrepeat"};
  284.     } elsif ($curappt{"endrepeat"}) {
  285.         $rule = $rule . " \#" . $curappt{"endrepeat"};
  286.     } else {
  287.         $rule = $rule . " \#0";
  288.     }
  289.     output($rule);
  290.     }
  291.     if (defined($curappt{"exceptions"})) {
  292.     $exceptions = "EXDATE:" . $curappt{"exceptions"};
  293.     chop($exceptions);
  294.     output($exceptions);
  295.     }
  296.     if (defined($curappt{"todo"})) {
  297.     if (defined($curappt{"done"})) {
  298.         output("STATUS:COMPLETED");
  299.     } else {
  300.         output("STATUS:NEEDS ACTION");
  301.     }
  302.     }
  303.     output("CLASS:PUBLIC");
  304.     output("PRIORITY:0");
  305.     output("TRANSP:0");
  306.     output("RELATED-TO:0");
  307.     if (defined($curappt{"todo"})) {
  308.     output("END:VTODO\n");
  309.     } else {
  310.     output("END:VEVENT\n");
  311.     }
  312. }
  313.  
  314. sub date_to_str
  315. {
  316.     $year = shift(@_);
  317.     $month = shift(@_);
  318.     $day = shift(@_);
  319.     my($datestr);
  320.     $datestr = sprintf("%04d%02d%02d",$year,$month,$day);
  321.     return $datestr;
  322. }
  323.  
  324. sub time_to_str
  325. {
  326.     $hour = shift(@_);
  327.     $min = shift(@_);
  328.     my($timestr);
  329.  
  330.     $timestr = sprintf("T%02d%02d00",$hour,$min);
  331.     return $timestr;
  332. }
  333.  
  334. sub process_dates
  335. {
  336.     # first, test for single
  337.     $_ = $line;
  338.     if (/\[Single/)  {
  339.     &repeat_none;
  340.     } elsif (/\[Days/) {
  341.     &repeat_daily;
  342.     } elsif (/\[WeekDays/) {
  343.     &repeat_weekly;
  344.     } elsif (/\[Months/) {
  345.     &repeat_monthly;
  346.     } elsif (/\[ComplexMonths/) {
  347.     $exitstatus = 1;
  348.     #printf("WARNING: complex repeating month entry detected, we don't support.\n");
  349.     #printf("converting to a single occurrence on the original start date.\n");
  350.     $line = &getLine;
  351.     &repeat_none;
  352.     } elsif (/\[Empty/) {
  353.     # silently toss
  354.     $curappt{"tossme"} = "TRUE";
  355.     } else {
  356.     $exitstatus = 1;
  357.     #print "didn't understand line: $_";
  358.     }
  359.     while ($line = &getLine) {
  360.     if ($line =~ /^\]/) {
  361.         return;
  362.     } elsif ($line =~ /^Finish/) {
  363.         ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
  364.         $curappt{"endrepeat"} = &date_to_str($year, $month, $day);
  365.         $curappt{"endrepeat"} = $curappt{"endrepeat"} . &time_to_str("0","0");
  366.     } elsif ($line =~ /^Deleted/) {
  367.         ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
  368.         if (defined($curappt{"exceptions"})) {
  369.         $curappt{"exceptions"} = $curappt{"exceptions"} .
  370.             &date_to_str($year, $month, $day) . ";";
  371.         } else {
  372.         $curappt{"exceptions"} = &date_to_str($year, $month, $day) .
  373.             ";";
  374.         }
  375.     } else {
  376.         $exitstatus = 1;
  377.         #print "trashed line: $line";
  378.     }
  379.     }
  380. }
  381.  
  382. sub repeat_none
  383. {
  384.     # just a one time shot
  385.     ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
  386.     $curappt{"startmonth"} = $month;
  387.     $curappt{"startday"} = $day;
  388.     $curappt{"startyear"} = $year;
  389. }
  390.  
  391. sub repeat_daily
  392. {
  393.     # repeats on a daily basis
  394.     $curappt{"repeats"} = "DAILY";
  395.     ($skip) = /(\d+)$/;
  396.     $curappt{"period"} = $skip;
  397.     $line = &getLine;
  398.     ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
  399.     $curappt{"startmonth"} = $month;
  400.     $curappt{"startday"} = $day;
  401.     $curappt{"startyear"} = $year;
  402. }
  403.  
  404. sub repeat_weekly
  405. {
  406.     # repeats on a weekly basis, a few days a week
  407.     $curappt{"repeats"} = "WEEKLY";
  408.     $startofdates = index($_,"WeekDays") + length("WeekDays");
  409.     $endofdates = index($_,"Months");
  410.     $datestr = substr($_,$startofdates,($endofdates-$startofdates));
  411.     $datestr =~ s/^\s+//;
  412.     @days = split(/\s+/,$datestr);
  413.     $datestr = "";
  414.     foreach $date (@days) {
  415.     if ($date == 1) {
  416.         $datestr = $datestr . "SU ";
  417.     } elsif ($date == 2) {
  418.         $datestr = $datestr . "MO ";
  419.     } elsif ($date == 3) {
  420.         $datestr = $datestr . "TU ";
  421.     } elsif ($date == 4) {
  422.         $datestr = $datestr . "WE ";
  423.     } elsif ($date == 5) {
  424.         $datestr = $datestr . "TH ";
  425.     } elsif ($date == 6) {
  426.         $datestr = $datestr . "FR ";
  427.     } elsif ($date == 7) {
  428.         $datestr = $datestr . "SA ";
  429.     }
  430.     }
  431.     # remove one trailing whitespace
  432.     chop($datestr);
  433.     $curappt{"weekdays"} = $datestr;
  434.     $line = &getLine;
  435.     ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
  436.     $curappt{"startmonth"} = $month;
  437.     $curappt{"startday"} = $day;
  438.     $curappt{"startyear"} = $year;
  439. }
  440.  
  441. sub repeat_monthly
  442. {
  443.     # repeats on a daily basis
  444.     $curappt{"repeats"} = "MONTHLY";
  445.     ($skip) = /(\d+)$/;
  446.     $curappt{"period"} = $skip;
  447.     $line = &getLine;
  448.     ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
  449.     $curappt{"startmonth"} = $month;
  450.     $curappt{"startday"} = $day;
  451.     $curappt{"startyear"} = $year;
  452. }
  453.  
  454.  
  455.